package com.oocl.crm.base;

/**
 * 基础双向链表
 * 
 * @author GANAB
 * 
 */
public abstract class DLinkedList<T> {
	private int size;
	private DNode<T> first;
	private DNode<T> last;

	public DLinkedList() {
		this.size = 0;
		this.first = null;
		this.last = null;
	}

	/**
	 * 在链表尾部批量新增节点
	 * 
	 * @param data
	 */
	public void batchInit(T[] array) {
		for (T t : array) {
			addLastNode(t);
		}
	}

	/**
	 * 是否为空链表
	 * 
	 * @return
	 */
	public boolean isEmpty() {
		return this.size == 0;
	}

	/**
	 * 在链表头部新增节点
	 * 
	 * @param data
	 */
	public void addFirstNode(T data) {
		if (this.isEmpty()) {
			this.first = new DNode<T>(data);
			this.last = this.first;
		} else {
			DNode<T> newNode = new DNode<T>(data);
			this.first.prev = newNode;
			newNode.next = this.first;
			this.first = newNode;
		}
		this.size++;
	}

	/**
	 * 在链表尾部新增节点
	 * 
	 * @param data
	 */
	public void addLastNode(T data) {
		if (this.isEmpty()) {
			this.last = new DNode<T>(data);
			this.first = this.last;
		} else {
			DNode<T> newNode = new DNode<T>(data);
			this.last.next = newNode;
			newNode.prev = this.last;
			this.last = newNode;
		}
		this.size++;
	}

	/**
	 * 根据下标获取链表节点
	 * 
	 * @param index
	 */
	public DNode<T> get(int index) {
		if (index > this.size || index < 0) {
			throw new IndexOutOfBoundsException("Index out if bounds " + index);
		}
		DNode<T> other = first;
		for (int i = 0; i < index; i++) {
			other = other.next;
		}
		return other;
	}

	/**
	 * 移除链表数据
	 * 
	 * @param index
	 */
	public boolean remove(int index) {
		if (index > this.size || index < 0) {
			throw new IndexOutOfBoundsException("Index out if bounds " + index);
		}
		DNode<T> targetNode = get(index);
		if (targetNode == null) {
			return true;
		} else {
			if(targetNode.next == null){
				System.out.println("last");
			}
			if(targetNode.prev == null){
				System.out.println("first");
			}
			targetNode.next.prev = targetNode.prev;
			targetNode.prev.next = targetNode.next;
			targetNode = null;
			this.size--;
			return true;
		}
	}

	/**
	 * 输出链表
	 */
	public void println() {
		DNode<T> temp = this.first;
		while (temp != null) {
			System.out.println(temp.data + " ");
			temp = temp.next;
		}
	}

	public int getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}
	
	public void autoIncrementSize() {
		this.size++;
	}
	
	public void autoSubductionSize() {
		this.size--;
	}

	public DNode<T> getFirst() {
		return first;
	}

	public void setFirst(DNode<T> first) {
		this.first = first;
	}

	public DNode<T> getLast() {
		return last;
	}

	public void setLast(DNode<T> last) {
		this.last = last;
	}
	
	

}
